package game_user

import (
	"time"

	"gddgame.cc/galaxy/common/dsl/game"
	"gddgame.cc/galaxy/common/dsl/game/stat"
	"gddgame.cc/galaxy/common/dsl/game/task"
	"gddgame.cc/galaxy/common/dsl/game/user"
	"gddgame.cc/galaxy/common/service/generate_name"
	"gddgame.cc/galaxy/common/service/playbook"
	"gddgame.cc/galaxy/core/models"
	"gddgame.cc/galaxy/utils"
	"gddgame.cc/galaxy/utils/def"
)

type UserDelegate interface {
	GetUserFromOpen(open *models.UserOpen) user.UserBase
}

type PlayerManager struct {
	delegate  UserDelegate
	env       *game.Environment
	userData  *user.UserData
	taskData  *task.TaskData
	PlayerMap map[string]int
	UserMap   map[string]user.UserBase

	HasAi bool
}

func NewPlayerManager(env *game.Environment, data *user.UserData, delegate UserDelegate) *PlayerManager {
	manager := &PlayerManager{
		delegate:  delegate,
		env:       env,
		userData:  data,
		PlayerMap: map[string]int{},
		UserMap:   map[string]user.UserBase{},
	}

	return manager
}

func (manager *PlayerManager) SetTaskData(data *task.TaskData) {
	manager.taskData = data
}

func (manager *PlayerManager) GetPlayerInfo(player *playbook.Player, taskIds []int) {
	var err error
	status := manager.env.GetUserStatus(player.OpenId)
	player.Language = game.DefaultLanguage
	player.TeamToken = utils.ToString(status[game.TeamKey])
	if value, ok := status[game.LanguageKey]; ok {
		player.Language = value.(string)
	}
	if player.OpenId != "" {
		player.Open, _ = manager.env.GetOpen(player.OpenId)
	}
	if player.Open == nil && player.Ai {
		name := generate_name.RandomChinese()
		t := time.Now()
		player.Open = &models.UserOpen{Id: player.OpenId, NickName: name, Avatar: "", LastTime: &t}
	}
	u := manager.delegate.GetUserFromOpen(player.Open)
	manager.UserMap[player.OpenId] = u
	if !player.Ai && taskIds != nil && len(taskIds) > 0 && manager.taskData != nil {
		if player.RealTaskProcess, err = manager.taskData.GetTaskProcess(u.GetId(), taskIds); err != nil {

		}
	}
	manager.PlayerMap[player.OpenId] = len(manager.PlayerMap) - 1
	if player.Ai {
		manager.HasAi = true
	}
}

func (manager *PlayerManager) GetUserBase(openId string) user.UserBase {
	return manager.UserMap[openId]
}

func (manager *PlayerManager) UpdateUserStats(context def.Context, player *playbook.Player, user user.UserBase, data *stat.StatData) error {
	if err := manager.userData.GetUserStats(context, user, data); err != nil {
		return err
	}
	for k, v := range player.Playbook {
		if v == 0 {
			continue
		}
		_ = user.GetStats().ChangeStats(context, k, v, false)
	}
	return nil
}
